Optional Tweening.f

{

Usage example:   ['] !   ['] exponential-ease   object ->x  dup @  5.0   50 tween-out

Tweens are currently blocking and so are intended to be executed by tasks.
This is handy for sequencing things though it isn't the most efficient.

This is in evaluation and the usage semantics may change.

TO DO:
  Inherit the task structure and use fields instead of locals, which will make debugging easier.
  Tweens ring - you must specify a ring when you want to create a new tween; it will be allocated from the chunk heap and added to the ring


}

Requires Linked-lists
Requires SORA\Tasks

Only Forth Definitions


: do-:const  does> @ ;
: :const   create do-:const here 0 , :noname swap ! ;

\ Transform the parameters to create other curves
' noop constant in
:const out   negate 1.0 + >r swap over + swap negate r> ;
:const in-out
  dup 0.5 < if swap 2/ swap 2*
    else swap 2/ rot over + -rot swap 0.5 - 2* [ out compile, ] then ;

\ Eases - All these describe the "in" animations

:const linear-ease  ( startval ratio. change. -- val )
  .* + ;

2e fconstant 2e
\ c * Math.pow(2, 10 * (t / d - 1)) + b;
:const exponential-ease ( startval change. ratio. -- val )
  1.0 - 10.0 .* 2e .>f f**
  f>. .* + ;

:const sine-ease ( startval change. ratio. -- val )
  90.0 .* 90.0 - .sin 1.0 + .* + ;

\   return c * (t /= d) * t + b;
:const quadratic-ease ( startval change. ratio. -- val )
  dup .* .* + ;

\  return c * (t /= d) * t * t + b;
:const cubic-ease  ( startval change. ratio. -- val )
  dup .* dup .* .* + ;

:const quartic-ease  ( startval change. ratio. -- val )
  dup .* dup .* dup .* .* + ;

:const quintic-ease  ( startval change. ratio. -- val )
  dup .* dup .* dup .* dup .* .* + ;

\  return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
:const circular-ease   ( startval change. ratio. -- val )
  dup .* 1.0 swap - .sqrt 1.0 - .* negate + ;

1.70158 value overshoot

\  return c * (t /= d) * t * ((s + 1) * t - s) + b;
:const back-ease  ( startval change. ratio. -- val )
  dup dup overshoot 1.0 + .* overshoot - .* .* .* + ;


: (tween) ( 'ease 'in/out addr startval change frames '! -- )
  >r 1 max 1.0 over / r>
  locals| '! interval frames change startval addr 'in/out 'ease |
  0  frames 0 do
    interval +
    startval change third 'in/out execute
       'ease execute addr '! execute
    pause
  loop  drop
  startval change + addr '! execute ;

: tween ( 'ease 'in/out addr dest frames -- )
   >r   over @ swap over -
   r> ['] ! (tween) ;

: ctween ( 'ease 'in/out addr dest frames -- )
   >r   over c@ swap over -
   r> ['] c! (tween) ;

: htween ( '! 'ease 'in/out addr dest frames -- )
   >r   over h@ swap over -
   r> ['] h! (tween) ;


\ Test
\\


generate dup << 1.0 1.0 1.0 sx 3v! >> constant obj
task: tx   tx main add-task
task: ty   ty main add-task

\ :noname ! ; constant [!]

: tween1
   ['] ! ['] linear-ease ['] out obj << x >> dup @ 200.0 150 tween  ;

: tween2
   ['] ! ['] sine-ease ['] out obj << y >> dup @ 200.0 150 tween ;

: test
   2dmode
   0 tx act:[ tween1 doze ;]
   0 ty act:[ tween2 doze ;]
   ;

: go  200 0 do pause cls mv-identity obj << transform >> gl-transform2d box end-frame loop ;
